package xin.ryven.car.android.download

import android.content.Context
import android.util.Log
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import okhttp3.Request
import xin.ryven.car.android.data.Music
import xin.ryven.car.android.utils.FileUtils
import java.io.File
import java.io.FileOutputStream
import java.util.concurrent.TimeUnit

object FileDownloader {
    private val client = OkHttpClient()

    suspend fun downloadFile(
        context: Context,
        music: Music,
        onProgress: (Int) -> Unit
    ): Boolean {
        return try {
            // 下载音乐文件 (70% 的进度)
            val musicFile = FileUtils.getMusicFile(context, music)
            download(music.downloadUrl, musicFile) { progress ->
                onProgress((progress * 0.7).toInt())
            }

            // 下载歌词文件 (10% 的进度)
            if (!music.lrcUrl.isNullOrEmpty()) {
                val lrcFile = FileUtils.getLrcFile(context, music)
                download(music.lrcUrl, lrcFile) { progress ->
                    onProgress(70 + (progress * 0.1).toInt())
                }
            }

            // 下载封面文件 (20% 的进度)
            if (!music.covers.isNullOrEmpty()) {
                val coverFile = FileUtils.getCoverFile(context, music.covers.split(",").firstOrNull() ?: "")
                download(music.covers, coverFile) { progress ->
                    onProgress(80 + (progress * 0.2).toInt())
                }
            }

            onProgress(100)
            true
        } catch (e: Exception) {
            Log.e("FileDownloader", "Download failed for ${music.name}", e)
            false
        }
    }

    suspend fun download(url: String, outputFile: File, onProgress: (Int) -> Unit = {}) = withContext(Dispatchers.IO) {
        try {
            val request = Request.Builder()
                .url(url)
                .build()

            client.newCall(request).execute().use { response ->
                if (!response.isSuccessful) {
                    throw Exception("Download failed with code ${response.code}")
                }

                val body = response.body ?: throw Exception("Empty response body")
                val contentLength = body.contentLength()
                var bytesRead = 0L

                outputFile.parentFile?.mkdirs()
                FileOutputStream(outputFile).use { output ->
                    body.byteStream().use { input ->
                        val buffer = ByteArray(8192)
                        var bytes: Int
                        while (input.read(buffer).also { bytes = it } != -1) {
                            output.write(buffer, 0, bytes)
                            bytesRead += bytes
                            if (contentLength > 0) {
                                val progress = ((bytesRead * 100) / contentLength).toInt()
                                withContext(Dispatchers.Main) {
                                    onProgress(progress.coerceIn(0, 100))
                                }
                            }
                        }
                    }
                }
            }
        } catch (e: Exception) {
            Log.e("FileDownloader", "Download failed for $url", e)
            throw e
        }
    }

    suspend fun downloadFile(
        url: String,
        file: File,
        onProgress: (Int) -> Unit
    ): Boolean = withContext(Dispatchers.IO) {
        try {
            val client = OkHttpClient.Builder()
                .connectTimeout(15, TimeUnit.SECONDS)
                .readTimeout(15, TimeUnit.SECONDS)
                .build()

            val request = Request.Builder()
                .url(url)
                .build()

            client.newCall(request).execute().use { response ->
                if (!response.isSuccessful) {
                    return@withContext false
                }

                val body = response.body
                val contentLength = body?.contentLength() ?: -1L
                val inputStream = body?.byteStream()

                if (inputStream == null) {
                    return@withContext false
                }

                FileOutputStream(file).use { output ->
                    val buffer = ByteArray(8 * 1024)
                    var bytesRead: Int
                    var totalBytesRead = 0L

                    while (inputStream.read(buffer).also { bytesRead = it } != -1) {
                        output.write(buffer, 0, bytesRead)
                        totalBytesRead += bytesRead

                        if (contentLength > 0) {
                            val progress = ((totalBytesRead * 100) / contentLength).toInt()
                            withContext(Dispatchers.Main) {
                                onProgress(progress)
                            }
                        }
                    }
                }

                true
            }
        } catch (e: Exception) {
            e.printStackTrace()
            false
        }
    }
} 